from django.shortcuts import render
from django.views import View
from django.http import JsonResponse

import json

from book.models import BookInfo
# Create your views here.


class BookDetailView(View):
    """
    显示指定图书：GET
    修改指定图书：PUT
    删除指定图书：DELETE
    """
    def get(self, request, pk):
        """
        新增图书
        路由：GET  /books/<pk>/
        """
        # 省略参数校验
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return JsonResponse({'code': 404, 'errmsg': '数据不存在'})
        return JsonResponse({
            'code': 200,
            'errmsg': '查询成功',
            'book':{
                "id": book.id,
                "commentcount": book.commentcount,
                "pub_date": book.pub_date,
                "readcount": book.readcount,
                "name": book.name,
                "image": str(book.image)
            }
        })

    def put(self, request, pk):
        """
        修改图书
        路由：PUT  /books/<pk>/
        """
        json_dict = json.loads(request.body.decode())
        commentcount = json_dict.get('commentcount')
        readcount = json_dict.get('readcount')
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return JsonResponse({'code': 404, 'errmsg': '数据不存在'})

        book.readcount = readcount
        book.commentcount = commentcount
        book.save()

        return JsonResponse({
            'code': 200,
            'errmsg': '修改数据成功',
            'book':{
                "id": book.id,
                "commentcount": book.commentcount,
                "pub_date": book.pub_date,
                "readcount": book.readcount,
                "name": book.name,
                "image": str(book.image)
            }
        })

    def delete(self, request, pk):
        """
        删除
        路由：DELETE  /books/<pk>/
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except BookInfo.DoesNotExist:
            return JsonResponse({'code': 404, 'errmsg': '数据不存在'})

        book.delete()
        return JsonResponse({'code': 200, 'errmsg': '删除数据成功'})


class BookListView(View):
    """
    新增图书：POST
    显示所有图书：GET
    """
    def post(self, request):
        """
        新增图书
        路由：POST /books/
        """
        # 获取参数
        json_dict = json.loads(request.body.decode())
        name = json_dict.get('name')
        pub_date = json_dict.get('pub_date')

        # 校验参数：省略

        # 数据保存
        try:
            book = BookInfo.objects.create(
                name=name,
                pub_date=pub_date
            )
        except BookInfo.DoesNotExist:
            return JsonResponse({'code': 404, 'errmsg': '数据库保存失败'})
        return JsonResponse({'code': 200, 'errmsg': '添加数据成功'})

    def get(self, request):
        """
        显示所有图书
        路由：GET /books/
        """
        books = BookInfo.objects.all()
        book_list = []
        for book in books:
            book_list.append({
                "id": book.id,
                "commentcount": book.commentcount,
                "pub_date": book.pub_date,
                "readcount": book.readcount,
                "name": book.name,
                "image": str(book.image)
            })
        return JsonResponse({'code': 200, 'errmsg': '查询数据成功', 'books': book_list})


from book.serializer import BookInfoSerializer
from book.models import BookInfo
book = BookInfo.objects.get(id=1)
s1 = BookInfoSerializer(instance=book)
s1.data
"""
{'id': 1, 'name': '射雕英雄传', 'pub_date': '1980-05-01', 'readcount': 12, 'commentcount': 34, 'image': None}
"""

books = BookInfo.objects.all()
s2 = BookInfoSerializer(books, many=True)
s2.data

"""
books 为查询集，在对查询集进行序列化时，需要指定many=True，否则会报错：
AttributeError: Got AttributeError when attempting to get a value for field `name` on serializer `BookInfoSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `QuerySet` instance.
Original exception text was: 'QuerySet' object has no attribute 'name'.
其中：（QuerySet' object has no attribute 'name'，序列化类中第一个属性）
[OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pub_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('image', None)]), 
OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', 24'), ('readcount', 36), ('commentcount', 40), ('image', None)]), 
OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('image', None),
OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_date', '1987-11-11'), ('readcount', 58), ('commentcount', 24), ('image', None)]), 
OrderedDict([('id', 5), ('name', '西游记后传'), ('pub_date', '1'), ('readcount', 0), ('commentcount', 0), ('image', None)])]
"""

"""
人物序列化一
1、需求为：输出字典格式为{'id': 10, ..., 'book_id': 3}
2、关联字段序列化方式：book_id = serializers.IntegerField(label='书籍id')
"""
from book.models import PeopleInfo
from book.serializer import PeopleInfoSerializer
people = PeopleInfo.objects.get(id=1)
s3 = PeopleInfoSerializer(instance=people)
s3.data
# {'id': 1, 'name': '郭靖', 'gender': 1, 'description': '降龙十八掌', 'book_id': 1}

"""
人物序列化方法二
1、需求为：输出字典格式为{'id': 10, ..., 'book': 3}
2、关联字段序列化方式：book = serializers.PrimaryKeyRelatedField(label='书籍id', read_only=True或者查询集)
"""
from book.models import PeopleInfo
from book.serializer import PeopleInfoSerializer
people = PeopleInfo.objects.get(id=1)
s4 = PeopleInfoSerializer(instance=people, read_only=True)
s4.data
# {'id': 1, 'name': '郭靖', 'gender': 1, 'description': '降龙十八掌', 'book': 1}

"""
人物序列化方法三
1、需求为：输出字典格式为{'id': 10, ..., 'book': '射雕英雄传'}
2、关联字段序列化方式：book = serializers.StringRelatedField(label='图书')
其中StringRelatedField关联的是BookInfo模型类中的__str__方法

"""
from book.models import PeopleInfo
from book.serializer import PeopleInfoSerializer
people = PeopleInfo.objects.get(id=1)
s6 = PeopleInfoSerializer(instance=people)
s6.data
# {'id': 1, 'name': '郭靖', 'gender': 1, 'description': '降龙十八掌', 'book': '射雕英雄传'}

"""
人物序列化方法四
1、需求为：输出字典格式为{'id': 10, ..., 'book': {}}
2、关联字段序列化方式：book = BookInfoSerializer()
"""
from book.models import PeopleInfo
from book.serializer import PeopleInfoSerializer
peoples = PeopleInfo.objects.all()
s7 = PeopleInfoSerializer(instance=peoples, many=True)
s7.data


# ==============================反序列化===========================
from book.serializer import BookInfoSerializer
data = {
    'name':'Python高级',
    'pub_date':'2020-1-1',
    'readcount':100,
    'commentcount':200
}
s1 = BookInfoSerializer(data=data)
s1.is_valid()
# False
s1.errors
# {'id': [ErrorDetail(string='该字段是必填项。', code='required')], 'image': [ErrorDetail(string='没有提交任何文件。', code='required')]}


"""
注意1：执行save()之前一定要进行数据验证，否则报错
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/ubuntu/.virtualenvs/Django/lib/python3.6/site-packages/rest_framework/serializers.py", line 178, in save
    'You must call `.is_valid()` before calling `.save()`.'
AssertionError: You must call `.is_valid()` before calling `.save()`.

注意2：执行save()之前一定要重写create()方法，否则会报错
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/ubuntu/.virtualenvs/Django/lib/python3.6/site-packages/rest_framework/serializers.py", line 212, in save
    self.instance = self.create(validated_data)
  File "/home/ubuntu/.virtualenvs/Django/lib/python3.6/site-packages/rest_framework/serializers.py", line 167, in create
    raise NotImplementedError('`create()` must be implemented.')
NotImplementedError: `create()` must be implemented.

"""
from book.serializer import BookInfoSerializer
data = {
    'id': 6,
    'name':'Python高级',
    'pub_date':'2020-1-1',
    'readcount':56,
    'commentcount':20
}
s1 = BookInfoSerializer(data=data)
s1.is_valid()
s1.save()
# False

"""
注意1：执行save()之前一定要进行数据验证，否则报错
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/ubuntu/.virtualenvs/Django/lib/python3.6/site-packages/rest_framework/serializers.py", line 178, in save
    'You must call `.is_valid()` before calling `.save()`.'
AssertionError: You must call `.is_valid()` before calling `.save()`.

注意2：如果是更新，执行save()之前一定要重写update()方法，否则会报错
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/ubuntu/.virtualenvs/Django/lib/python3.6/site-packages/rest_framework/serializers.py", line 207, in save
    self.instance = self.update(self.instance, validated_data)
  File "/home/ubuntu/.virtualenvs/Django/lib/python3.6/site-packages/rest_framework/serializers.py", line 164, in update
    raise NotImplementedError('`update()` must be implemented.')

注意3：更新和保存新数据的区别：
更新：s1 = BookInfoSerializer(instance=book, data=data)
保存新数据：s2 = BookInfoSerializer(data=data)
"""
from book.serializer import BookInfoSerializer
from book.models import BookInfo
book = BookInfo.objects.get(id=1)
data = {
    'name':'Python高 级',
    'pub_date':'2020-1-1',
    'readcount':56,
    'commentcount':20
}
s1 = BookInfoSerializer(instance=book, data=data)
s1.is_valid()
s1.save()

from book.serializer import PeopleInfoSerializer
data = {
    'name':'杨伟宏',
    'niuibi':'0',
    'renxing':'True',
    'description': '帅',
    'book':6
}
s2 = PeopleInfoSerializer(data=data)